﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Reflection;

namespace One.Framework.UI.Security
{
    /// <summary>
    /// System.Web.Security.CookieProtectionHelper 랩핑 클래스
    /// MachineKey 를 기준으로 엔코딩 디코딩을 수행한다.
    /// </summary>
    public static class CookieProtectionHelperWrapper
    {
        private static MethodInfo encode;
        private static MethodInfo decode;

        static CookieProtectionHelperWrapper()
        {
            Assembly systemWeb = typeof(HttpContext).Assembly;

            if (systemWeb == null)
            {
                throw new InvalidOperationException("Unalbe to load System.Web");
            }

            Type cookieProtectionHelper = systemWeb.GetType("System.Web.Security.CookieProtectionHelper");

            if (cookieProtectionHelper == null)
            {
                throw new InvalidOperationException("Unalbe to get the internal class CookieProtectionHelper");

            }

            encode = cookieProtectionHelper.GetMethod("Encode", BindingFlags.NonPublic | BindingFlags.Static);
            decode = cookieProtectionHelper.GetMethod("Decode", BindingFlags.NonPublic | BindingFlags.Static);

            if (encode == null || decode == null)
            {
                throw new InvalidOperationException("Unalbe to get Methods to invoke");
            }
        }

        /// <summary>
        /// auth cookie 엔코딩하는 내부 메소드를 랩핑
        /// </summary>
        /// <param name="cookieProtection">암호화 레벨</param>
        /// <param name="buf">문자열 byte</param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static string Encode(CookieProtection cookieProtection, byte[] buf, int count)
        {
            return (string)encode.Invoke(null, new object[] { cookieProtection, buf, count });
        }

        /// <summary>
        /// auth cookie 디코딩하는 내부 메소드를 랩핑
        /// </summary>
        /// <param name="cookieProtection"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] Decode(CookieProtection cookieProtection, string data)
        {
            return (byte[])decode.Invoke(null, new object[] { cookieProtection, data });
        }
    }
}
